/**
 * 桌面通知和声音提示工具
 */

import { isTauri } from '../services/secure-storage';

/**
 * 检查是否在 Tauri 环境中
 */
function checkTauri(): boolean {
  return isTauri();
}

/**
 * 请求桌面通知权限
 */
export async function requestNotificationPermission(): Promise<boolean> {
  // 在 Tauri 环境中，需要检查并请求通知权限
  if (checkTauri()) {
    try {
      const { isPermissionGranted, requestPermission } = await import('@tauri-apps/plugin-notification');
      
      // 检查是否已授予权限
      let permissionGranted = await isPermissionGranted();
      
      // 如果未授予权限，请求权限
      if (!permissionGranted) {
        const permission = await requestPermission();
        permissionGranted = permission === 'granted';
      }
      
      return permissionGranted;
    } catch (error) {
      console.error('Tauri 通知权限请求失败:', error);
      return false;
    }
  }

  if (!('Notification' in window)) {
    console.warn('此浏览器不支持桌面通知');
    return false;
  }

  if (Notification.permission === 'granted') {
    return true;
  }

  if (Notification.permission !== 'denied') {
    const permission = await Notification.requestPermission();
    return permission === 'granted';
  }

  return false;
}

/**
 * 显示桌面通知
 */
export async function showNotification(
  title: string,
  options?: NotificationOptions
): Promise<Notification | null> {
  // 在 Tauri 环境中使用原生通知
  if (checkTauri()) {
    try {
      const { sendNotification, isPermissionGranted } = await import('@tauri-apps/plugin-notification');
      
      // 检查权限
      const permissionGranted = await isPermissionGranted();
      if (!permissionGranted) {
        console.warn('Tauri 通知权限未授予');
        return null;
      }
      
      // 发送通知
      await sendNotification({
        title,
        body: options?.body,
        icon: options?.icon || '/logo.png',
        sound: options?.silent !== true ? 'default' : undefined,
        tag: options?.tag || 'violet-im',
      });
      
      return null; // Tauri 通知不返回 Notification 对象
    } catch (error) {
      console.error('显示 Tauri 通知失败:', error);
      return null;
    }
  }

  // 浏览器环境使用标准 Web Notification API
  if (!('Notification' in window) || Notification.permission !== 'granted') {
    return null;
  }

  const defaultOptions: NotificationOptions = {
    icon: '/logo.png',
    badge: '/logo.png',
    tag: 'violet-im',
    requireInteraction: false,
    silent: false,
    ...options,
  };

  try {
    const notification = new Notification(title, defaultOptions);
    
    // 点击通知时聚焦到窗口
    notification.onclick = () => {
      window.focus();
      notification.close();
    };

    // 自动关闭通知（5秒后）
    setTimeout(() => {
      notification.close();
    }, 5000);

    return notification;
  } catch (error) {
    console.error('显示桌面通知失败:', error);
    return null;
  }
}

/**
 * 播放提示音
 */
export function playNotificationSound(): void {
  try {
    // 创建一个简单的提示音（使用 Web Audio API）
    const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();
    const oscillator = audioContext.createOscillator();
    const gainNode = audioContext.createGain();

    oscillator.connect(gainNode);
    gainNode.connect(audioContext.destination);

    // 设置音调（800Hz，类似"叮"的声音）
    oscillator.frequency.value = 800;
    oscillator.type = 'sine';

    // 设置音量（淡入淡出）
    gainNode.gain.setValueAtTime(0, audioContext.currentTime);
    gainNode.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + 0.01);
    gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + 0.3);

    oscillator.start(audioContext.currentTime);
    oscillator.stop(audioContext.currentTime + 0.3);
  } catch (error) {
    console.error('播放提示音失败:', error);
  }
}

/**
 * 呼叫铃声管理器
 */
class CallRingtoneManager {
  private audioContext: AudioContext | null = null;
  private oscillators: OscillatorNode[] = [];
  private gainNode: GainNode | null = null;
  private intervalId: number | null = null;
  private isPlaying = false;

  /**
   * 播放呼叫铃声（循环播放，真实电话铃声效果）
   */
  start(): void {
    if (this.isPlaying) {
      return;
    }

    try {
      this.audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();
      this.gainNode = this.audioContext.createGain();
      this.gainNode.connect(this.audioContext.destination);
      this.gainNode.gain.value = 0.4; // 音量设置为40%

      this.isPlaying = true;
      this.playRingtone();

      // 每4秒播放一次铃声（真实电话铃声的节奏：响1秒，停3秒）
      this.intervalId = window.setInterval(() => {
        if (this.isPlaying) {
          this.playRingtone();
        }
      }, 4000);
    } catch (error) {
      console.error('播放呼叫铃声失败:', error);
      this.isPlaying = false;
    }
  }

  /**
   * 播放一次铃声（真实电话铃声效果：双音和弦）
   */
  private playRingtone(): void {
    if (!this.audioContext || !this.gainNode) {
      return;
    }

    try {
      const now = this.audioContext.currentTime;
      
      // 真实电话铃声使用两个频率同时播放（和弦效果）
      // 标准电话铃声频率：440Hz 和 480Hz（或 425Hz 和 480Hz）
      const freq1 = 440; // 第一个频率
      const freq2 = 480; // 第二个频率
      
      // 铃声持续约1秒，然后停止3秒
      const ringDuration = 1.0; // 铃声持续1秒
      const volume = 0.4; // 音量

      // 同时播放两个频率，产生和弦效果（真实电话铃声的特点）
      this.playDualTone(now, freq1, freq2, ringDuration, volume);
    } catch (error) {
      console.error('播放铃声失败:', error);
    }
  }

  /**
   * 播放双音和弦（两个频率同时播放，模拟真实电话铃声）
   */
  private playDualTone(startTime: number, freq1: number, freq2: number, duration: number, volume: number): void {
    if (!this.audioContext || !this.gainNode) {
      return;
    }

    try {
      // 创建两个振荡器（两个频率）
      const osc1 = this.audioContext.createOscillator();
      const osc2 = this.audioContext.createOscillator();
      
      // 为每个振荡器创建独立的增益节点
      const gain1 = this.audioContext.createGain();
      const gain2 = this.audioContext.createGain();

      // 设置振荡器类型和频率
      // 使用方波或正弦波，真实电话铃声通常使用方波
      osc1.type = 'square'; // 方波，更接近真实电话铃声
      osc1.frequency.value = freq1;
      
      osc2.type = 'square';
      osc2.frequency.value = freq2;

      // 连接音频节点
      osc1.connect(gain1);
      osc2.connect(gain2);
      gain1.connect(this.gainNode);
      gain2.connect(this.gainNode);

      // 设置音量包络（模拟真实电话铃声的起振和衰减）
      // 真实电话铃声有快速的起振和缓慢的衰减
      const attackTime = 0.01; // 快速起振（10ms）
      const sustainTime = duration * 0.8; // 保持80%的时间
      const releaseTime = duration * 0.2; // 缓慢释放（20%的时间）

      // 第一个频率的音量包络
      gain1.gain.setValueAtTime(0, startTime);
      gain1.gain.linearRampToValueAtTime(volume * 0.5, startTime + attackTime); // 快速起振
      gain1.gain.setValueAtTime(volume * 0.5, startTime + sustainTime); // 保持
      gain1.gain.linearRampToValueAtTime(0, startTime + duration); // 缓慢释放

      // 第二个频率的音量包络（稍微延迟，产生更丰富的音色）
      gain2.gain.setValueAtTime(0, startTime + 0.005);
      gain2.gain.linearRampToValueAtTime(volume * 0.5, startTime + attackTime + 0.005);
      gain2.gain.setValueAtTime(volume * 0.5, startTime + sustainTime);
      gain2.gain.linearRampToValueAtTime(0, startTime + duration);

      // 启动和停止振荡器
      osc1.start(startTime);
      osc1.stop(startTime + duration);
      osc2.start(startTime + 0.005);
      osc2.stop(startTime + duration);

      // 保存引用以便清理
      this.oscillators.push(osc1, osc2);

      // 清理已停止的振荡器
      osc1.onended = () => {
        const index = this.oscillators.indexOf(osc1);
        if (index > -1) {
          this.oscillators.splice(index, 1);
        }
      };
      osc2.onended = () => {
        const index = this.oscillators.indexOf(osc2);
        if (index > -1) {
          this.oscillators.splice(index, 1);
        }
      };
    } catch (error) {
      console.error('播放双音和弦失败:', error);
    }
  }

  /**
   * 停止播放呼叫铃声
   */
  stop(): void {
    this.isPlaying = false;

    if (this.intervalId !== null) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }

    // 停止所有振荡器
    this.oscillators.forEach(osc => {
      try {
        osc.stop();
      } catch (error) {
        // 忽略已停止的振荡器错误
      }
    });
    this.oscillators = [];

    // 关闭音频上下文
    if (this.audioContext) {
      this.audioContext.close().catch(() => {
        // 忽略关闭错误
      });
      this.audioContext = null;
    }

    this.gainNode = null;
  }
}

// 创建全局的呼叫铃声管理器实例
let callRingtoneManager: CallRingtoneManager | null = null;

/**
 * 开始播放呼叫铃声
 */
export function startCallRingtone(): void {
  if (!callRingtoneManager) {
    callRingtoneManager = new CallRingtoneManager();
  }
  callRingtoneManager.start();
}

/**
 * 停止播放呼叫铃声
 */
export function stopCallRingtone(): void {
  if (callRingtoneManager) {
    callRingtoneManager.stop();
  }
}

/**
 * 显示新消息通知（桌面通知 + 声音）
 */
export async function notifyNewMessages(
  totalUnread: number,
  unreadChats: Array<{ name: string; unread_count: number; chat_type: number }>
): Promise<void> {
  if (totalUnread <= 0) {
    return;
  }

  // 请求通知权限
  const hasPermission = await requestNotificationPermission();

  if (hasPermission) {
    // 构建通知内容
    const chatNames = unreadChats.slice(0, 3).map(chat => chat.name).join('、');
    const title = totalUnread > 1 
      ? `您有 ${totalUnread} 条未读消息`
      : '您有 1 条未读消息';
    
    const body = unreadChats.length > 0
      ? `${chatNames}${unreadChats.length > 3 ? ' 等' : ''}发来新消息`
      : '您有新的消息';

    await showNotification(title, {
      body,
      icon: '/logo.png',
      badge: '/logo.png',
      tag: 'violet-im-new-messages',
    });
  }

  // 播放提示音（如果用户允许）
  // 在 Tauri 环境中，通知声音由系统处理，不需要额外播放
  if (!checkTauri()) {
    playNotificationSound();
  }
}

